#pragma once

#include <qbmessage/include/message_bond.h>
#include <qbmessage/include/message_process.h>
#include <qbprotocol/include/SSQBModel.h>
#include <qbprotocol/include/SSQBQuote.h>
#include <string.h>

#include <algorithm>
#include <list>
#include <map>
#include <string>
#include <vector>

#include "Define.h"
#include "core/Utility.h"
#include "core/system/critical_section_wrapper.h"

#ifndef WIN32
#include <pthread.h>
#endif
#include "qbprotocol/include/rdProto.h"

#define QB_BROKER_BESTQUOTE 99
#define USER_PERMISSION_BOND_MARKETSTREAM \
  "quoteboard.bond.marketstream"  // MarketStream权限
#define USER_PERMISSION_BOND_DEALHIS \
  "quoteboard.bond.bondhis"  // 经纪商成交历史
// #define USER_PERMISSION_BOND_DEALHIS_TP
// "quoteboard.bond.bondhis.tpsc"			//国利成交历史 #define
// USER_PERMISSION_BOND_DEALHIS_ICAP
// "quoteboard.bond.bondhis.cfic"			//国际成交历史 #define
// USER_PERMISSION_BOND_DEALHIS_TP
// "quoteboard.bond.bondhis.patr"			//平安成交历史 #define
// USER_PERMISSION_BOND_DEALHIS_TP
// "quoteboard.bond.bondhis.tjxt"			//信唐成交历史 #define
// USER_PERMISSION_BOND_DEALHIS_TP
// "quoteboard.bond.bondhis.cbbj"			//BGC成交历史
#define USER_PERMISSION_BOND_ALLTABLE "quoteboard.bond.alltable"  // All-tab权限
#define USER_PERMISSION_BOND_MMQUOTEMANAGER \
  "quoteboard.bond.mmquotemanager"  // MM报价管理权限
#define USER_PERMISSION_QUOT_MMSHARE \
  "quoteboard.quot.mmshare"  // MM分享报价权限
#define USER_PERMISSION_QMFALG "quoteboard.quotemessage"  // 启用QM权限
#define USER_PERMISSION_PALEADSHIP "quoteboard.paleadership"  // 平安旗舰店权限
#define USER_PERMISSION_BROKERPRICE \
  "quoteboard.brokerprice"  // 查看经纪商报价权限
#define USER_PERMISSION_REPURCHASECALC \
  "quoteboard.repurchasecalc"  // 回购计算器权限
#define USER_PERMISSION_QUOT_BONDQUOT \
  "quoteboard.bondquotemanager"  // 债券报价权限
#define USER_PERMISSION_PRIMARY_SHOWOFFLINE \
  "quoteboard.primary.showoffline"  // 显示一级线下申购
#define USER_PERMISSION_QUOTE_ALLMARKET \
  "quoteboard.mmquot.allmarket"                    // 发向全市场的权限
#define USER_PERMISSION_CDB "cdb"                  // 国开行
#define USER_PERMISSION_CPIC "INVEST.RESTRICTION"  // 太保投资
#define USER_PERMISSION_DEBUGER "quoteboard.debuger"  // 测试员权限
#define USER_PERMISSION_MATRIX "quoteboard.transsta.matrix"  // 成交统计矩阵显示
#define USER_PERMISSION_IAS "IAS"  // 投资分析管理
#define USER_PERMISSION_WEB_INTERBANK \
  "quoteboard.web.interbankquote"  // 线下同业报价
#define USER_PERMISSION_EXPIREREMINDER \
  "quoteboard.expirereminder"  // 到期提醒弹框

#define USER_PERMISSION_EXCEL_LOGIN "excel.login"      // Excel登录权限
#define USER_PERMISSION_EXCEL_HISTORY "excel.history"  // Excel历史数据权限
#define USER_PERMISSION_EXCEL_REAL "excel.real"  // Excel实时数据权限
#define USER_PERMISSION_EXCEL_FUNCTION "excel.function"  // Excel静态函数权限
#define USER_PERMISSION_EXCEL_BOND_HISTORY_TP \
  "Excel.TP.history"  // ExcelAddin TP历史数据权限
#define USER_PERMISSION_EXCEL_HISTORY_TF \
  "Excel.TF.history"  // ExcelAddin国债期货历史数据权限
#define USER_PERMISSION_EXCEL_ARBITRAGE \
  "Excel.Arbitrage"  // ExcelAddin东方证券权限
#define USER_PERMISSION_EXCEL_HEDGING "Excel.Hedging"  // ExcelAddin东方证券权限
#define USER_PERMISSION_EXCEL_BOND_EOD_LIMIT \
  "Excel.Bond.EodLimit"  // ExcelAddin中指定时间段使用Bond数据权限
#define USER_PERMISSION_EXCEL_TF_EOD_LIMIT \
  "Excel.TF.EodLimit"  // ExcelAddin中指定时间段使用Bond数据权限
#define USER_PERMISSION_EXCEL_ABN_PRC_REMINDER \
  "Excel.AbnormalPrice.Reminder"                           // 异常价格提醒
#define USER_PERMISSION_SPREADINDEX "quoteboard.web.lcxs"  // 光大利差
#define USER_PERMISSION_MYDAILY "quoteboard.web.wdrb"      // 我的日报
#define USER_PERMISSION_CMOS "quoteboard.coms"             // 大行资金
#define USER_PERMISSION_EXCEL_MONEYMARKET_COLUMN \
  "Excel.MoneyMarket.Column"  // money market列权限
#define USER_PERMISSION_MYPURCHASE "quoteboard.mypurchase"  // 旧版我的申购
#define USER_PERMISSION_WEB_MYPURCHASE \
  "quoteboard.web.mypurchase"  // 我的申购网页版
#define USER_PERMISSION_BOCKH_DIMSUM \
  "quoteboard.dimsumbond.upload"  // 中银香港点心债
#define USER_PERMISSION_MUWNOTICE "quoteboard.muwnotice"    // 主承公告
#define USER_PERMISSION_MYSCORE "quoteboard.myscore"        // 我的积分
#define USER_PERMISSION_NGPC "quoteboard.ngpc.irtender"     // 利率招标室
#define USER_PERMISSION_NGPC_CORP "quoteboard.ngpc.corp"    // 公司债
#define USER_PERMISSION_NGPC_PPN "quoteboard.ngpc.ppn"      // ppn
#define USER_PERMISSION_NGPC_SALES "quoteboard.ngpc.sales"  // 我是销售
#define USER_PERMISSION_WEB_BONDDETAIL \
  "quoteboard.web.bonddetail"  // 债券详情网页版
#define USER_PERMISSION_DEAL_EXPORT \
  "quoteboard.deal.export"  // 成交统计导出权限
#define USER_PERMISSION_DEAL_EXPORT_NEW \
  "quoteboard.deal.exportnew"  // 成交统计新导出权限
#define USER_PERMISSION_DEAL_EXPORT_LOOK \
  "quoteboard.deal.exportlook"  // 成交统计查看权限
#define USER_PERMISSION_DEAL_PANARAMA \
  "quoteboard.deal.panarama"  // 成交统计全景统计
#define USER_PERMISSION_WEB_CHINESEDOLLORBOND \
  "quoteboard.web.chinesedollarbond"  // 成交统计全景统计

#define USER_PERMISSION_TF_EXPORT "quoteboard.TF.export"  // 国债期货导出权限
#define USER_PERMISSION_TF_EXPORT_HISTORY \
  "quoteboard.tf.export.history"  // 国债期货导出历史行情权限，禁用(0)，授权(1)，试用(2)
#define USER_PERMISSION_TF_EXPORT_REALTIME \
  "quoteboard.tf.export.realTime"  // 国债期货导出当日行情权限，禁用(0)，授权(1)
#define USER_PERMISSION_TF_LEVERL2 "quoteboard.TF.levelTwo"  // 国债期货level2
#define USER_PERMISSION_TF_LEVEL1 "quoteboard.TF.levelOne"  // 国债期货功能开关

#define USER_PERMISSION_WEB_CNEX "quoteboard.web.cnex"  // CNEX资金情绪
#define USER_PERMISSION_WEB_CFETS_MM "quoteboard.web.cfets.mm"  // CFETS货币市场

#define USER_PERMISSION_WEBBOND_CFETS "quoteboard.webbond.cfets"  // CFETS权限
#define USER_PERMISSION_CFETS_DEAL_EXPORT \
  "quoteboard.deal.export.cfets"  // CFETS导出成交

#define USER_PERMISSION_BOND_SSE "qeubee.bond.sse"  // 上交所
#define USER_PERMISSION_BOND_SZE "qeubee.bond.sze"  // 深交所
#define USER_PERMISSION_GTJA_ADMIN \
  "quoteboard.gtja.admin"  // 国泰君安管理员权限

#define USER_PERMISSION_EXCEL_REAL "excel.real"  // Excel实时数据权限
#define USER_PERMISSION_EXCEL_FUNCTION "excel.function"  // Excel静态函数权限
#define USER_PERMISSION_EXCEL_QUANTITY_FLOW \
  "excel.quantity.flow"                            // 账户每月总流量
#define USER_PERMISSION_EXCEL_RESET "excel.reset"  // 流量重置标识
#define USER_PERMISSION_QB_PRO \
  "quoteboard.qbpro.license"  // 0 - 普通版 1 - 收费版 2 - Datafeed版
#define USER_PERMISSION_IRS_COM_QUOTE "qeubee.irs.com.quote"  // IRS综合行情
#define USER_PERMISSION_QIDIAN "qeubee.qidian"                // 企点应用
#define USER_PERMISSION_IDCCLIENT "idc.client"  // QB看IDC系统权限，IDCClient
#define USER_PERMISSION_MOBILE_VERIFY "qb.user.mobile.verify"  // 手机验证权限
#define USER_PERMISSION_CHINABONDRATINGG \
  "qeubee.chinabondrating"  // 中债资信授权
#define USER_PERMISSION_CSI_IMPLICITRATING \
  "qeubee.csi.implicitrating"  // 中证隐含评级

// #define USER_PERMISSION_SHOWBROKERTAG
// "qeubee.showbrokertag"
// //显示经纪商标签，4.8版本仅成交统计页面使用
#define USER_PERMISSION_SHOWBROKERTAG_REALTIME "qeubee.showbrokertag.realTime"
#define USER_PERMISSION_SHOWBROKERTAG_HISTORY "qeubee.showbrokertag.history"
#define USER_PERMISSION_ABS_CALCULATOR "qeubee.abs.calculator"  // ABS计算器权限
#define USER_PERMISSION_WEB_CREDB "quoteboard.ngpc.credb"  // 信用发行社
#define USER_PERMISSION_ENGLISH "qeubee.english"           // 英文版权限
#define USER_PERMISSION_NEW_QM "qeubee.page.newqm"  // 我的手账本，新版QM
#define USER_PERMISSION_QM_BROKER_CONTACT \
  "qeubee.qm.brokercontact"  // newqm打开常用经纪人
#define USER_PERMISSION_ABS_CHINA_RATING \
  "qeubee.abs.china.rating"  // ABS计算器中债资信TAB权限
#define USER_PERMISSION_ABS_MOODY "qeubee.abs.moody"  // ABS计算器MoodyTAB权限
#define USER_PERMISSION_ABS_CNABS "qeubee.abs.cnabs"  // ABS计算器CnabsTAB权限
#define USER_PERMISSION_RT_SPREAD_ADMIN \
  "qeubee.rtspread.administor"  // 实时利差的管理员权限
#define USER_PERMISSION_BONDDATAEXPLORER_EXPORT \
  "qeubee.bonddataexplorer.export"  // 债券浏览器，导出权限
#define USER_PERMISSION_BONDDATAEXPLORER_BROKEREXPORT \
  "qeubee.bonddataexplorer.brokerexport"  // 债券浏览器经纪商数据导出权限,0禁用
                                          // 1开通
#define USER_PERMISSION_BONDDATAEXPLORER_BROKERVIEW \
  "qeubee.bonddataexplorer.brokerview"  // 债券浏览器经纪商数据查看权限,0禁用
                                        // 1开通

#define USER_PERMISSION_CHECK_HANGDUMP \
  "qeubee.check.hangdump"  // 检测UI卡顿，0禁用，1使用procdump，2使用内嵌工具
#define USER_PERMISSION_BROKER_BESTQUOTE "qeubee.brokerbq"  // 经纪商最优报价

#define USER_PERMISSION_WEB_IRSCALC "quebee.web.irscalcnew"
#define USER_PERMISSION_WEB_ANALYSIS "qeubee.web.analysis"

#define USER_PERMISSION_BOND_BESTQUOTE \
  "qeubee.bond.bestquote"  // 经纪商最优行情

// 市场 global setting
#define SWITCH_QB_EXCHANGE_SSE "switch_qb_exchange_sse"  // 上海交易所行情切换
#define SWITCH_QB_EXCHANGE_SZE "switch_qb_exchange_sze"  //

#define SWITCH_QB_EXCHANGE_SERVICE "switch_qb_exchange_service"  // 后台服务上线

class S_UAM_EXPORT CShowUnitInfo {
 public:
  std::string m_BrokerID;
  std::string m_AllowName;
  std::string m_Abbr;
  std::string m_AllowNameEn;
  std::string m_BusinessCode;  // 业务代码
  std::string
      m_BusinessLevel;  // 服务器设置：1-普通用户，2-优惠卖家，3-优惠买家，4-全优惠
  int m_Order;
};

class S_UAM_EXPORT CBusinessShowInfo {
 public:
  std::vector<CShowUnitInfo> m_AllowList;
};

/// 拉点详情///
class AutBusi_Compare {
 public:
  AutBusi_Compare(const char* pChar) { m_bussinessLevel.append(pChar); }
  bool operator()(xQBAuthorityBusiness_c& stUnit) {
    if (std::string(stUnit.m_BusinessLevel) == m_bussinessLevel) return true;
    return false;
  }

 private:
  std::string m_bussinessLevel;
};

class S_UAM_EXPORT CLevelItem {
 public:
  char m_BusinessType[32 + 1];   // 业务类型
  char m_BusinessLevel[32 + 1];  // 业务基本
  char m_ItemKey[128];           // key
  char m_Value[64];              // Value
  char m_BrokerID[32 + 1];       // 经纪公司ID
  char m_CompanyType[4];         // 1--机构报价  Leaf， 0--经纪公司
  char m_PriceType
      [32];  // 方案拉点时使用的价格类型.BILATERAL:双边报价,INDICATIVE:参考价
  char m_MemoFlag[8];  // 方案是否有备注.0：无,1:有
  CLevelItem() {}
  CLevelItem(const char* brokerID, const char* pCompanyType,
             const char* pBusinessType, const xLevelItem_c& xItem) {
    // FIELDCOPY(m_BrokerID,brokerID);
    FIELDCOPY(m_BrokerID, brokerID);
    FIELDCOPY(m_CompanyType, pCompanyType);
    FIELDCOPY(m_BusinessType, pBusinessType);
    FIELDCOPY(m_BusinessLevel, xItem.m_BusinessLevel);
    FIELDCOPY(m_ItemKey, xItem.m_ItemKey);
    FIELDCOPY(m_Value, xItem.m_Value);
    FIELDCOPY(m_PriceType, xItem.m_PriceType);
    FIELDCOPY(m_MemoFlag, xItem.m_MemoFlag);
  }
  bool operator==(const CLevelItem& stItem) {
    if (strcmp(m_ItemKey, stItem.m_ItemKey) == 0 &&
        strcmp(m_BrokerID, stItem.m_BrokerID) == 0)
      return true;
    return false;
  }
};
class S_UAM_EXPORT CLevelItemList {
 public:
  std::list<CLevelItem> m_List;

  //    bool Insert(char* brokerID,char* pCompanyType,xLevelItem_c xItem);
  bool Insert(const CLevelItem& cpLevelItem);
  void clear() { m_List.clear(); }
  bool GetLevelItem(const char* brokerID, const char* pszKey,
                    CLevelItem& stItem);
};
//////经纪公司，m_CompanyType == 0
class S_UAM_EXPORT CBrokerUnit {
 public:
  CBrokerUnit()
      : m_brokerID(-1),
        m_enableFlag_BOND(false),
        m_enableFlag_NCD(false),
        m_enableFlag_IRS(false),
        m_bQuotationSilent(false) {}

 public:
  int m_brokerID;                // 经纪公司ID
  std::string m_brokerCode;      // 代码
  std::string m_brokerName;      // 简称
  std::string m_brokerENName;    // 名称
  std::string m_brokerFullName;  // 全称
  std::string m_address;         // 地址
  std::string m_postCode;        // 邮编
  std::string m_tel;             // 电话
  std::string m_fax;             // 传真
  std::string m_email;
  bool m_enableFlag_BOND;                         // BOND允许标志
  bool m_enableFlag_NCD;                          // NCD允许标志
  bool m_enableFlag_IRS;                          // IRS 允许标志
  bool m_bQuotationSilent;                        // 行情静默标志
  std::list<xQBTradeCmpContact_c> m_ContactList;  // 公司联系信息
  std::list<xQBAuthorityBusiness_c>
      m_BusinessList;  // 业务列表，一个经济公司有多个业务，如债券,IRS等
  std::map<std::string, int>
      m_DefaultContact;  // 默认联系人，key = "利率债"，"信用债"，"NCD"
 public:
  int GetDefaultContactID(const char* skey) const;
  const char* GetDefaultContactQQ(const char* skey) const;
};

class S_UAM_EXPORT CBrokerContact {
 public:
  enum eDeptType { eDeptNone = 0, eDeptRating, eDeptCredit, eDeptNCD };
  CBrokerContact() : m_brokerID(-1), m_deptType(eDeptNone){};

 public:
  int m_brokerID;
  eDeptType m_deptType;  // 经纪人台子枚举
  std::string m_astNm;   // 经纪人名称
  //	std::string	m_astParentTp;	//资产大类，利率，信用，NCD
  std::string m_qmid;  // qm账号
};

typedef std::map<int, CBrokerContact> CBrokerContacts;
typedef std::map<int, CBrokerContacts> CBrokerContactsMap;

//////报价金融机构，m_CompanyType == 1
class S_UAM_EXPORT CQuoteBankUnit {
 public:
  std::string m_BCCompanyID;                // 机构ID
  std::string m_BCCode;                     // 机构代码
  std::string m_BCName;                     // 机构名称
  std::string m_BCDetail;                   // 机构简介
  std::list<xQBBondBCContact_c> m_Contact;  // 联系人列表
  std::list<xQBAuthorityBusiness_c>
      m_BusinessList;  // 业务列表，一个经济公司有多个业务，如债券,IRS等
};

class S_UAM_EXPORT CQuoteBankList {
 public:
  std::map<std::string, CQuoteBankUnit>
      m_mapBank;  //<银行ID,银行详情> key:m_BCCompanyID
};

//////用户信息
class S_UAM_EXPORT CUserAccountInfo {
 public:
  char m_UserAccount[64 + 1];       // 用户名
  char m_UserLoginAccount[32 + 1];  // 用户登录名 手机号或者邮箱
  char m_UserId[32 + 1];            // 用户id
  char m_Password[32 + 1];          // 用户密码
  char m_DisplayName[32];           // 用户显示名
  char m_DisplayName_Utf8
      [32];  // 用户显示名, utf8编码，建议所有显示用户名的地方，都使用utf8编码
  char m_CompanyId[32 + 1];  // 所属机构id
  char m_CompanyName[32];    // 所属机构
  char m_AccountType[32];    // 账号类型
  char m_ExpireDate[12];     // 账号到期日
  char m_Title[32];          // 职位、头衔
  char m_Telephone[32];      // 电话
  char m_Mobile[32];         // 手机
  char m_Rm[32];             // Reuters Messager
  char m_Msn[32];            // msn
  char m_QQ[32];
  char m_Address[50];               // 地址
  char m_BankName[32 + 1];          // 与账户相关的银行名称
  char m_CSQBAccount[32 + 1];       // 客户经理QBAccount
  char m_CSChineseName[32 + 1];     // 客户经理中文名
  char m_CSEnglishName[32 + 1];     // 客户经理英文名
  char m_CSTelephone[32 + 1];       // 固定电话
  char m_CSMobile[32 + 1];          // 手机号码
  char m_CSEmail[128 + 1];          // 电子邮箱
  char m_SponsorsName[64 + 1];      // 赞助机构名称
  char m_SponsorsID[32 + 1];        // 赞助机构ID
  char m_Department[32];            // 部门
  char m_BussinessType[64];         // 业务类型
  char m_QQEnterprise[32];          // 企点QQ员工号
  char m_QQEnterprise_Company[32];  // 企点QQ机构号

  bool m_CSAgent;
  std::list<QBAccountInfoNewAckUnit> m_lstPhone;  // 5个电话号码,5个手机号码
  CUserAccountInfo();
};

//////用户手机验证情况
class S_UAM_EXPORT CUserMobileConfirmInfo : public xQBMobileVerifyInfoAck_c {
 public:
  CUserMobileConfirmInfo();
  virtual ~CUserMobileConfirmInfo();
  void SetParams(const xQBMobileVerifyInfoAck_c* param);

  /*有没有初始,需要确认收到过应答*/
  bool IsInitial();

  /*下次再说*/
  bool NextTime();

 private:
  bool m_Initial;
};

class S_UAM_EXPORT CBrokerList {
 public:
  typedef std::map<int, CBrokerUnit> BrokerMap;
  typedef std::list<xQBTradeCmpyInfo_c> CompanyList;
  typedef std::vector<int> SortIdList;
  typedef std::list<xQBAuthorityBusiness_c> BusinessList;
  friend class SSUserAccountManager;
  friend class Writer;

  CBrokerList() : m_nSaveSortIdType(0) {}
  CBrokerList(const CBrokerList& brokerList)
      : m_sortid(brokerList.m_sortid),
        m_bond_business_level(brokerList.m_bond_business_level),
        m_mapBroker(brokerList.m_mapBroker),
        m_BrokerDailyCompany(brokerList.m_BrokerDailyCompany),
        m_nSaveSortIdType(brokerList.m_nSaveSortIdType) {}

 private:
  SortIdList m_sortid;
  std::string m_bond_business_level;
  BrokerMap m_mapBroker;             //<公司ID,经纪公司详情>
  CompanyList m_BrokerDailyCompany;  // 允许放日评的经纪公司

  int m_nSaveSortIdType;  // 0表示默认值(不修正状态位，兼容旧版)，1表示保存上一次值
                          // ，2表示不保存上一次值
 public:
  const CBrokerUnit& GetBrokerUnit(int brokerId) const;
  const BrokerMap& GetBrokerMap() const { return m_mapBroker; }
  const CompanyList& GetCompanyList() const { return m_BrokerDailyCompany; }
  const std::string& GetBondBusinessLevel() const {
    return m_bond_business_level;
  }
  const SortIdList& GetSortKey() const { return m_sortid; }
  int GetSaveSortIdType() const { return m_nSaveSortIdType; }
  void SetSaveSortIdType(int nValue) { m_nSaveSortIdType = nValue; }
  bool IsSaveSortId() const { return m_nSaveSortIdType == 1; }
  static bool IsValidBroker(int brokerId) {
    return (brokerId > 0 && brokerId <= 6) || brokerId == 98;
  }  // 判定有效经纪商id
  static bool IsValidBroker_All(int brokerId) {
    return (brokerId >= 0 && brokerId <= 6) || brokerId == 98;
  }  // 判定有效经纪商id，包括 allbroker

 protected:
  BrokerMap& GetBrokerMap() { return m_mapBroker; }
  void AddSortKey(const int& key);
  void RemoveSortKey(const int& key);
  void ClearSortKey() { m_sortid.clear(); }
  void IniSortKey();
  void SetBondBusinessLevel(const std::string& strLevel) {
    m_bond_business_level = strLevel;
  }
  void SetCompanyList(const CompanyList& compList) {
    m_BrokerDailyCompany = compList;
  }

 public:
  class S_UAM_EXPORT Writer {
    CBrokerList& m_brokerlist;
    int m_changed_count;

   public:
    Writer(const Writer&);
    Writer& operator=(const Writer&);

   public:
    Writer(CBrokerList& brokerlist)
        : m_brokerlist(brokerlist), m_changed_count(0) {}
    ~Writer();
    CBrokerList& GetBrokerList() { return m_brokerlist; }

    // Business
    void ClearAllBusinessList();
    void AddBusiness(int brokerid, const xQBAuthorityBusiness_c& business);

    // Contact
    void ClearAllContactList();
    void AddContact(int brokerid, const xQBTradeCmpContact_c& contact);
    BusinessList& GetBusinessList(int brokerid);
    void SetBONDEnableFlag(int brokerid, bool enable);
    void SetNCDEnableFlag(int brokerid, bool enable);
    void SetIRSEnableFlag(int brokerid, bool enable);
    void SetQuotationSilent(int brokerid, bool bSilent);
    void Apply(int brokerid, const std::string& sBusinessAllowId);
    void SetBondBusinessLevel(const std::string& strLevel) {
      m_changed_count++;
      m_brokerlist.SetBondBusinessLevel(strLevel);
    }
    void IniSortKey() {
      m_changed_count++;
      m_brokerlist.IniSortKey();
    }
    void ClearSortKey() {
      m_changed_count++;
      m_brokerlist.ClearSortKey();
    }
    void RemoveSortKey(const int& key) {
      m_changed_count++;
      m_brokerlist.RemoveSortKey(key);
    }
    void AddSortKey(const int& key) {
      m_changed_count++;
      m_brokerlist.AddSortKey(key);
    }
    void SetCompanyList(const CompanyList& compList) {
      m_changed_count++;
      m_brokerlist.SetCompanyList(compList);
    }
    void UpdateBrokerInfo(const xQBTradeCmpyInfo_c& cmpy);
    void SetDefaultContact(int brokerid, const char* skey, int contactid);
  };
};
/*
        每个线程读取时,都将从m_writer中复制出来
                如果状态一致,复制步骤直接跳过
        每个线程写入,先复制出来,最后写到m_writer中,并更新状态
*/
class CBrokerListHost {
  class CFastLock {
    qb::CriticalSectionWrapper* m_cs;

   public:
    CFastLock() { m_cs = qb::CriticalSectionWrapper::CreateCriticalSection(); }
    ~CFastLock() {
      if (m_cs) delete m_cs;
      m_cs = NULL;
    }
    bool Lock() {
      if (m_cs) m_cs->Enter();
      return true;
    }
    bool UnLock() {
      if (m_cs) m_cs->Leave();
      return true;
    }
    class Scoped {
      CFastLock* mx;

     public:
      Scoped(CFastLock& m) : mx(&m) { mx->Lock(); }
      ~Scoped() { mx->UnLock(); }
    };
  };
  struct BrokerListInfo {
    int stateid;              // 状态ID,每次改写都将递增
    CBrokerList* brokerlist;  // 指针
    BrokerListInfo() : stateid(0), brokerlist(0) {}
    BrokerListInfo(const BrokerListInfo& bli)
        : stateid(bli.stateid), brokerlist(bli.brokerlist) {}
    BrokerListInfo& operator=(const BrokerListInfo& bli) {
      stateid = bli.stateid;
      brokerlist = bli.brokerlist;
      return *this;
    }
  };
  typedef std::map<unsigned long, BrokerListInfo> BrokerListInfoMap;
  BrokerListInfoMap m_reader;
  BrokerListInfo m_writer;
  CFastLock m_lock;

 public:
  CBrokerListHost();
  ~CBrokerListHost();
  int GetReaderCount() {
    CFastLock::Scoped scoped(m_lock);
    return m_reader.size();
  }
  const CBrokerList& GetReader() { return GetReaderImpl(); }
  CBrokerList& GetWriter() { return GetReaderImpl(); }
  void Update(const CBrokerList& broker);

 protected:
  CBrokerList& GetReaderImpl();
};

// 数据库实时推送升级权限等数据
class S_UAM_EXPORT CUserAccountUpdateInfo {
 public:
  char m_ID[32 + 1];
  char m_UserName[64];
  int m_UpdateRight;  // 升级权限
  int m_QBFlag;
  CUserAccountUpdateInfo() {
    m_ID[0] = '\0';
    m_UserName[0] = '\0';
    m_UpdateRight = 0;
    m_QBFlag = 0;
  }
};

class S_UAM_EXPORT SSUserPermission {
 protected:
  std::map<std::string, std::string> m_list;
  std::map<std::string, xQBUserpermApplyData> m_status;

 public:
  SSUserPermission();
  ~SSUserPermission();

  void SetValue(const char* szPermIndex, const char* szPermValue);
  const char* GetValue(const char* szPermIndex);

  void SetStatus(const xQBUserpermApplyData& data);
  bool GetStatus(const char* szPermIndex, xQBUserpermApplyData& data);
};

// 报价共享被共享的常用联系人账号信息
class S_UAM_EXPORT CSSQuoteSharedAccount {
 public:
  CSSQuoteSharedAccount() { m_QuoteSharedAccList.clear(); }

 public:
  std::list<std::string> m_QuoteSharedAccList;
};

// 本地配置，原option.ini
class CSSUserWebOption_Imp;
class S_UAM_EXPORT CSSUserWebOption {
 public:
  CSSUserWebOption();
  ~CSSUserWebOption();

 public:
  void AddURL(const char* sKey, const char* sValue);
  const char* LoadURL(const char* sKey);

  void Load();
  void Save();

 private:
  CSSUserWebOption_Imp* m_pImp;
};

// 目录菜单，menu.json
class CQBAppMenu_Imp;
class S_UAM_EXPORT CQBAppMenu {
 public:
  CQBAppMenu(const char* sType);
  ~CQBAppMenu();

 public:
  void SetMenu(const char* sMenu, bool bFinished);
  int GetMenu(std::string& sMenu);

 private:
  CQBAppMenu_Imp* m_pImp;
};

class S_UAM_EXPORT CUserMemberInfo {
 public:
  void UpdateMemberInfo(const xUserMemberInfoAck_c* pRawData,
                        time_t tServerTime);

 public:
  char m_UserId[33];         // 用户ID
  char m_UserAccount[64];    // QB用户名（QM登录名）
  char m_CompanyId[32 + 1];  // 所属机构id，新增
  char m_MemberLevel[2];     // 1-5级， 会员另外表示
  char m_IsPaidCustom[2];  // 是否付费用户， “1"表示付费，“0”或""表示普通用户
  int m_CurrentMonthBp;  // 当期Bp, 登录Bp + 打开页面Bp, 各有阈值
  int m_TotalBp;         // 累积Bp
  int m_OpenPageBpCanGetToday;  // 通过打开页面还能获取多少Bp,需要后台判断是否达到阈值
  char m_FirstLogInReceived[2];  // “1”表示可以发第一次登录的请求，
                                 // “0”或“”表示没有收到
  char m_FirstOpenRecommendReceived
      [2];  //"1"表示可以发了第一次打开页面的请求，“0”或“”表示没有收到
  char m_openPageName[66];  // 推荐页面名称
  bool m_bLevelChanged;
  bool m_bOpenPageNotice;
  int m_bOpenPageGetBp;
  std::list<sUserMemberLevelList> m_ListLevel;  // 会员level对应Bp 值，可配

  time_t m_updateTime;
  bool m_bDayChanged;

  CUserMemberInfo() {
    _InitializeString(m_UserId);
    _InitializeString(m_UserAccount);
    _InitializeString(m_CompanyId);
    _InitializeString(m_MemberLevel);
    _InitializeString(m_IsPaidCustom);
    m_CurrentMonthBp = 0;
    m_TotalBp = 0;
    m_OpenPageBpCanGetToday = 0;
    _InitializeString(m_FirstLogInReceived);
    _InitializeString(m_FirstOpenRecommendReceived);
    _InitializeString(m_openPageName);
    m_bLevelChanged = false;
    m_bOpenPageNotice = false;
    m_bOpenPageGetBp = 0;
    m_updateTime = 0;
    m_bDayChanged = true;
  }
};

struct UAM_IDCPermission {
  bool idc;
  bool idcconnet;
  UAM_IDCPermission() : idc(false), idcconnet(false){};
};

class S_UAM_EXPORT SSUserAccountManager : public QObject,
                                          public IQpidMessageProcessor,
                                          public IMessageProcessorOnSubThread {
  Q_OBJECT
 public:
  static SSUserAccountManager& instance();
  void init();

 private:
  SSUserAccountManager(void);
  virtual ~SSUserAccountManager(void);
  typedef std::map<int, xCDCAuthorityUnit> CDCAuthorityUnitMap;

 private:
  std::string m_jsonAppMenu;  // QBApp目录菜单
  std::map<std::string, std::string>
      m_SystemVariabls;  // 系统开关，全局开关，全局设置等
  std::map<std::string, CLevelItemList>
      m_LevelList;  // 拉点详情列表, IRS, FX, Bond
  std::map<std::string, UAM_IDCPermission> m_IDCPermission;  // IDC权限
  CBrokerListHost m_BrokerList;  // 经纪公司列表，m_CompanyType == 0
  CBrokerContactsMap m_BrokerContacts;     // 经纪商联系人列表
  CUserAccountInfo m_UserInfo;             // 用户信息
  CUserMobileConfirmInfo m_MobileConfirm;  // 手机验证情况
  CQuoteBankList m_BankQuoteList;   // 报价银行列表 m_CompanyType == 1
  CBusinessShowInfo m_PrimaryAuth;  // 所有有权限的一级机构
  // CBusinessShowInfo	m_OTCOBackground;
  // //可进入的场外期权后台列表(By Dif) CBusinessShowInfo
  // m_OTCOForeground;			//可进入的场外期权前台列表(By Dif)
  SSUserPermission m_Permission;     // 用户权限列表
  CSSUserWebOption m_WebOptions;     // 网页配置
  CQBAppMenu m_Menu;                 // QB菜单
  CQBAppMenu m_MenuRelation;         // QB相关功能
  CQBAppMenu m_MenuCommont;          // QB菜单简介
  CUserMemberInfo m_UserMemberInfo;  // 获取用户会员相关信息
  bool m_bGotBrokerList;             // 是否已获取经纪公司
  bool m_bGotAuthList;               // 是否已获取一级分销公司列表
  bool m_bQuoteAuth;                 // 是否可以报价，true--可以报价
  // int				m_OverSeaFlag;
  // //VersionTypes Mainland_Version--国内，Oversea_Version--海外 int
  // m_PageOnFlag;
  // //显示隐藏部分页面的总开关，由服务器控制, 1 = 开， 0 = 关 int
  // m_QMOnFlag;					//关联QM总开关 QB2.0 , 1
  // = 开，0 = 关 int				m_ShowBrokerFlag;
  // //最优报价显示Broker标签开关，1=开，0=关
  bool m_bBrokerMobileOnline;  // 手机端在线
  bool m_bUseProtocol;         // 登记电子使用协议
  bool m_CSIAuthorityFlag;     // 中证估值权限

  CUserAccountUpdateInfo
      m_AccountUpdateData;  // 服务器推送的账户升级权限、QBFLAG等更新数据
  CSSQuoteSharedAccount m_QuoteSharedAccount;  // 报价被共享的常用联系人账号信息

  int m_CDCAuthorityOld;    // 估值权限，1=有，0=无
  bool m_CDCAuthoriryInit;  // 重新计算
  bool m_hasAnyCDCAuth;     // 是否有中债权限
  CDCAuthorityUnitMap
      m_CDCAuthority;  // 估值权限，1~10，modify by lance 2018.3.30

  bool m_hasAuthSSE{false};
  bool m_initAuthSSE{false};
  bool m_hasAuthSZE{false};
  bool m_initAuthSZE{false};

 public:
  enum bussinessType {
    typeNull = 0,    // 黑名单，或无效
    typeApply,       // 未申请，显示申请按钮
    typeApplyPass,   // 已审核，显示联系方式
    typeApplyNPass,  // 已拒绝，无法申请
    typeStop,        // 已停用，无法申请
    typeApplying     // 审核中，显示联系方式
  };

  // enum cdcauthorityFlag{
  //	flagcdcauthorityoff = 0,
  //	flagcdcauthorityon = 1
  // };

  enum globalvariables {
    PageOnFlag = 0,
    ShowBrokerFlag,
    RatingInstutionSort,
    WarningPayment,
    RecommendPageGetBpId,
    MobileVerifyTime,          // QB手机验证弹出时间
    ShowQidianBar,             // 显示企点Bar
    ShowTFStatisticsOverView,  // 显示TF统计-市场总览
    ShowQBLiveOverAll,         // 是否QBLive汇总页已经上线
    PageHomeUseNewIndex,       // 使用新版首页指数
    ShowBestPriceSettlement,   // 显示清算速度
    HideSettlementSpot,        // 显示清算速度-非远期
    ExchangeSSESwitch,         // 上交所时间切换
    ExchangeSZESwitch,         // 深交所行情时间切换
    SwitchExchangeService,     // 后台服务上线
    UseNewDealSource,          // 使用新数据源，V5.3.1.3
    ShowNewDealDetail          // 显示新数据源详细，V5.3.1.3
  };
  class CDCAuthKey {
    std::vector<bool> m_keys;

   protected:
    friend class SSUserAccountManager;
    explicit CDCAuthKey(int capcity) {
      m_keys.reserve(capcity <= 0 ? 16 : capcity);
    }
    void SetKey(int key) {
      if (key < 0) return;
      while ((int)m_keys.size() <= key) {
        m_keys.push_back(false);
      }
      m_keys[key] = true;
    }

   public:
    CDCAuthKey() { m_keys.reserve(16); }
    CDCAuthKey(const CDCAuthKey& authKey) {
      m_keys.clear();
      m_keys = authKey.m_keys;
    }
    CDCAuthKey& operator=(const CDCAuthKey& authKey) {
      m_keys.clear();
      m_keys = authKey.m_keys;
      return *this;
    }
    bool HasKey(int key) const {
      if (key <= 0) return true;
      if (key > 0 && key < (int)m_keys.size()) return m_keys[key];
      return false;
    }
  };
  static int GetBussinessState(int statusC, int statusT,
                               int statusB);  // 获取经纪公司权限状态
  static bool GetBussinessNoPass(int statusC, int statusT,
                                 int statusB);  // 获取经纪公司是否未获得授权

 public:
  CLevelItemList& GetLevelList(const char* pType);
  CLevelItemList& GetIRSLevelList();
  CLevelItemList& GetFXLevelList();
  CLevelItemList& GetFXOptionLevelList();
  CLevelItemList& GetBondLevelList();
  CBrokerList& GetBroker();
  const CBrokerList& GetReadonlyBroker();
  void UpdateBroker(const CBrokerList& brokerList);
  CQuoteBankList& GetQuoteBankList();
  SSUserPermission& GetPermission();
  CSSUserWebOption& GetWebOption();
  CUserMemberInfo& GetUserMemberInfo();
  bool GetPrimaryMarketAuth_SupMark(
      CBusinessShowInfo& showinfo);  // BOND_P.SuperMarket
  bool GetPrimaryMarketAuth_FlagShip(CBusinessShowInfo& showinfo);
  bool GetPrimaryMarketAuth_FlagShip_V2(CBusinessShowInfo& showinfo);
  bool GetPrimaryMarketAuthForSuperMarket(CBusinessShowInfo& showinfo);
  bool GetPrimaryMarketAuth_All(
      CBusinessShowInfo& showinfo);  // BOND_P + BOND_P.PA + BOND_P.LEADSHIP +
                                     // BOND_P.SuperMarket

  bool GetDimsumAuth_FlagShip(
      CBusinessShowInfo& showinfo);  // 点心债旗舰店 DIMSUM.LEADSHIP
  // 2016/08/24 by devin.zhang://判断是否有一级权限
  bool IsHavePrimaryAuth(const char* pszUwid = NULL);
  // 2018/04/23 by devin.zhang: //判断underwriterid是否有对应的权限
  bool IsHavePrimaryAuth(const char* pszUwid, const char* pszAuth);
  void UpdatePrimaryAuth();  // 生成m_PrimaryAuth
  void SetPrimaryAuthOrder(const char* pUUID, int Order);
  void SortPrimayMarketAuth();                   // 机构排序
  bool GetNCDAuth(CBusinessShowInfo& showinfo);  // NCD_P
  bool GetBankQuoteAuth(CBusinessShowInfo& showinfo);
  bool GetOTCOBackgroundAuth(
      CBusinessShowInfo& showinfo);  // 可进入的场外期权后台列表(By Lance)
  bool GetOTCOForegroundAuth(
      CBusinessShowInfo& showinfo);  // 可进入的场外期权前台列表(By Lance)
  bool GetFXSwapAuth(CBusinessShowInfo& showinfo);    // FX Swap权限
  bool GetFXOptionAuth(CBusinessShowInfo& showinfo);  // FX Option权限
  bool GetFXAuth(CBusinessShowInfo& showinfo);  // FX Swap + FX Option权限
  bool GetBondCopAuth(CBusinessShowInfo& showinfo);  // 机构债券报价权限
  bool SetBrokerDailyCompany(const void* pData);
  bool SetUserCSInfo(const void* pData);
  bool GetBrokerNameByID(int ID, char* strCompanyName, size_t nSize,
                         const char* strLanguage);
  //	bool	GetCFETS_Right();
  ////获取是否有权看外汇交易中心标志
  bool GetCFETS_Permission();  // 获取是否有权看外汇交易中心标志，3.4.0，Addby
                               // Lance 20170125
  bool GetCffex_Right();  // 获取是否有权看中金所行情标志
  bool GetExchange_Right();  // 获取是否有权看上海深圳交易所行情标志
  // 	bool	GetOTCOBackgroundAuth(CBusinessShowInfo & showinfo);
  // //是否有权打开场外期权后台管理页面 	bool
  // GetOTCOForegroundAuth(CBusinessShowInfo & showinfo);
  // //是否有权打开场外期权前台查看页面
  bool GetInvestRestrictionAuth(
      CBusinessShowInfo& showinfo);  // 获取投资限制权限列表
  bool GetExcelBond_Broker(
      CBusinessShowInfo& showinfo);  // BOND_EXCEL,Excel插件broker权限
  bool GetExcelHistoryAuth();        // 获取Excel历史数据权限
  bool GetExcelRealAuth();           // 获取Excel实时数据权限
  bool GetExcelFunctionAuth();       // 获取Excel静态函数权限
  bool GetExcelLoginAuth();
  const char* GetGlobleVariabl(int nKey);  // 获取全局开关，全市场设置
  int GetCDCAuthorityOld();
  const std::map<int, xCDCAuthorityUnit>& GetCDCAutority();  // 中债估值权限
  CDCAuthKey GetCDCAutorityKey();
  bool HasAnyCDCAuthority();

  bool HasAuthOfCDC(int nAuthNo = 7);
  bool HasAuthOfCSI();
  bool HasAuthOfCBR();

  bool GetSSE_Permission();  // 上交所
  bool GetSZE_Permission();  // 深交所
  bool IsExchangeTimeSwitch(const char* listedMarket);
  bool HasExchangeAuth(const char* lmMarket);
  void ResetExchangeInit();
  bool IsSwitchExchangeService();

  bool GetCSIAuthorityFlag() const;
  CUserAccountInfo& GetUserInfo();
  CUserMobileConfirmInfo& GetMobileConfirm();
  bool SetUserInfo(const void* pData, int nFuncID);
  bool SetUserInfo(const char* sUserID, const char* sPwdMD5,
                   const char* sCompanyID = NULL);
  bool SetBroker(const xQBTradeCmpyInfoListAck_c* pData);
  bool SetBrokerContacts(const std::string& sJson);
  bool SetQuoteBank(const void* pData);
  void SetCDCAutorityOld(int nAllow);
  void SetCDCAutority(const void* pData);
  void SetCSIAuthorityFlag(int flag);
  void SetAuthListFlag();
  void InitIDCPermission();
  void SetSystemVariabls(
      const std::map<std::string, std::string>& variableList);
  bool HasBrokerList();
  bool HasAuthList();
  void ResetBrokerList();
  bool AllowQuote();                        // 是否允许报价
  void SetAllowQuoteFlag(int bAllowQuote);  // 设置允许报价标志
  bool IsBrokerBondAvailable(const int& nCompanyID);
  bool IsBrokerBondAvailable(const char* sCompanyID);
  bool IsBrokerNCDAvailable(const int& nCompanyID);
  bool IsBrokerNCDAvailable(const char* sCompanyID);
  bool IsBrokerIRSAvailable(const int& nCompanyID);
  void InsertLevelItem(CLevelItem& item);
  bool IsBrokerDealHistoryAvailable(int nBrokerID);
  void SetBrokerMobileOnline(bool bOnline);
  bool IsBrokerMobileOnline();
  bool IsShowSettlement();
  bool IsHideSettlementSpot();

  void SetAccountUpdateInfo(
      const CUserAccountUpdateInfo&
          AccountUpdateInfo);  // 缓存服务器推送的账户升级权限等更新数据
  CUserAccountUpdateInfo& GetAccountUpdateInfo(
      void);  // 读取账户升级权限更新数据
  void SetQuoteSharedAccount(const CSSQuoteSharedAccount& QuoteSharedAcc);
  CSSQuoteSharedAccount& GetQuoteSharedAccount(void);

  bool GetPrimaryBrokerShowInfo(const char* sBrokerID, CShowUnitInfo& info);

  const char* GetUserAccount() const { return m_UserInfo.m_UserAccount; };
  const char* GetUserPassword() const { return m_UserInfo.m_Password; };

  bool isUsedProtocol();

  bool GetAllowBusinessAuth(CBusinessShowInfo& showinfo,
                            const char* pBusinessCode);
  // 	void	CheckIDCPermission(LPCSTR brokerID, bool& idc, bool&
  // idcconnect);

  void SetBrokerDefaultContact(const xQBFlagsAck_c* ack);

  bool GetBrokerContact(int nBrokerID, CBrokerContact::eDeptType nType,
                        CBrokerContact& brokerContact);
  // 大行资金
 public:
  void SetComsAuthority(int nValue) { m_nComsAuthority = nValue; };
  int GetComsAuthority() const { return m_nComsAuthority; }

  void SetComsAccessID(const char* sAccessID);
  const char* GetComsAccessID() const { return m_sComsAccessID; }

  void requestSystime();
  void requestBroker();
  void requestQbFlags();
  void requestGlobalSwitch();
  void requestUserInfo();
  void requestUserProtocol();
  void requestUserMemInfo();
  void requestUserAuthority();
  void requestMobileConfirm();
  void requestQBConditionGroupQueryNew();

 protected:
  bool HasAuthOfSSE();
  bool HasAuthOfSZE();
  STDMETHOD_(void, OnResponse)
  (THIS_ int32_t funcId, const qb::SSAckMsg&) override;
  STDMETHOD_(void, OnResponse)
  (THIS_ int32_t msgtype, qb::ProcessMessage msp) override;

  void timerEvent(QTimerEvent* event) override;

 signals:
  void recvSignal(xMarketSignalInfo_t signal);

 private:
  int m_nComsAuthority;      // 大行资金入口权限
  char m_sComsAccessID[33];  // accessID
  int m_sysTimerId = 0;
};

#define NEW_DETAIL_ALLTAB_BROKER 77
// 经纪商ID
#define VERIRY_BROKER_ID_INT(_INT_) (CBrokerList::IsValidBroker(_INT_))
#define VERIRY_BROKER_ID_STRING(_STR_) \
  (strlen(_STR_) > 0 && CBrokerList::IsValidBroker(atoi(_STR_)))

// CFETS brokerID
#define NEW_DETAIL_CFETS_BROKER 50
#define NEW_DETAIL_CFETS_BROKER_STRING "50"
#define VERIRY_IS_CFETST_BROKER_INT(_INT_) (_INT_ == 50)
#define VERIRY_IS_CFETST_BROKER_STRING(_STR_) \
  (strlen(_STR_) > 0 && strcmp(_STR_, "50") == 0)

// 交易所brokerID
#define NEW_DETAIL_EXCHANGE_BROKER 'e'
#define NEW_DETAIL_EXCHANGE_BROKER_STRING "e"
#define VERIRY_IS_EXCHANGE_BROKER_INT(_INT_) (_INT_ == 'e')
#define VERIRY_IS_EXCHANGE_BROKER_STRING(_STR_) \
  (strlen(_STR_) > 0 && strcmp(_STR_, "e") == 0)
